package com.bolingcavalry.crm.sales.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bolingcavalry.crm.product.mapper.ProductMapper;
import com.bolingcavalry.crm.sales.mapper.OrderProductMapper;

import com.bolingcavalry.crm.sales.mapper.SalesMapper;
import com.bolingcavalry.crm.sales.service.SalesService;
import com.dto.ProductDTO;
import com.dto.SalesOrderDTO;
import com.entity.sales0rder.OrderProduct;
import com.entity.product.Product;
import com.entity.sales0rder.SalesOrder;
import com.vo.ProductVO;
import com.vo.SalesOrderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SalesServiceImpl implements SalesService {
    @Autowired
    private SalesMapper salesMapper;
    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private ProductMapper productMapper;

    @Override
    @Transactional
    public Boolean addSelsOrder(SalesOrderDTO salesOrderDTO) {
        SalesOrder salesOrder = new SalesOrder();
        OrderProduct orderProduct = new OrderProduct();
        //复制salesOrderDTO同名字段给salesOrder
        BeanUtils.copyProperties(salesOrderDTO, salesOrder);
        //保存到订单表数据库中
        salesMapper.insert(salesOrder);
        //获取产品列表 （供货时间、产品名称、产品型号、规格、数量、材质、mpa、备注）
        ProductDTO[] salesProducts = salesOrderDTO.getSalesProducts();
        //获取配件列表（产品名称、产品型号、规格、数量、材质、mpa、备注）
        ProductDTO[] parts = salesOrderDTO.getParts();
        //将salesOrder保存到数据库中，存储订单产品信息到中间表中（产品id 订单id 数量 备注 供货时间）
        for (ProductDTO product : salesProducts) {
            orderProduct.setDeliveryTime(product.getDeliveryTime());
            orderProduct.setQuantity(product.getQuantity());
            orderProduct.setRemark(product.getRemark());
            orderProduct.setUnitPrice(product.getPrice());
            orderProduct.setSalesOrderId(salesOrder.getId());
            orderProduct.setProductId(product.getId());
            orderProduct.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
            orderProduct.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
            //保存到订单产品中间表数据库中
            orderProductMapper.add(orderProduct);
        }
        for (ProductDTO part : parts) {
            orderProduct.setDeliveryTime(part.getDeliveryTime());
            orderProduct.setQuantity(part.getQuantity());
            orderProduct.setRemark(part.getRemark());
            orderProduct.setUnitPrice(part.getPrice());
            orderProduct.setSalesOrderId(salesOrder.getId());
            orderProduct.setProductId(part.getId());
            orderProduct.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
            orderProduct.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
            //保存到订单产品中间表数据库中
            orderProductMapper.add(orderProduct);
        }

        return true;

    }

    /**
     * 更新销售订单（同时删除旧的中间表直接插入新的中间表，中间表是多对多的关系，所以数据可能存在多种，为保证一致性）
     * 前端传入的数据是完整的，作为中间表存放的产品和配件也是，所以当更新的时候会先删除之前的中间表，再根据这些数据插入新的数据到中间表
     * @param salesOrderDTO
     * @return
     */
    @Override
    @Transactional
    public Boolean updateSalesOrder(SalesOrderDTO salesOrderDTO) {
        //使用mp 更新订单表和订单产品中间表
        LambdaQueryWrapper<SalesOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SalesOrder::getId, salesOrderDTO.getId());
        SalesOrder salesOrder = new SalesOrder();
        BeanUtils.copyProperties(salesOrderDTO, salesOrder);
        try {
            salesMapper.update(salesOrder, queryWrapper);
        } catch (Exception e) {
            throw new RuntimeException("更新销售订单表失败");
        }
        //获取产品列表和零件列表合并为一个集合作为中间表插入
        ProductDTO[] productDTOs = new ProductDTO[salesOrderDTO.getSalesProducts().length + salesOrderDTO.getParts().length];
        System.arraycopy(salesOrderDTO.getSalesProducts(), 0, productDTOs, 0, salesOrderDTO.getSalesProducts().length);
        System.arraycopy(salesOrderDTO.getParts(), 0, productDTOs, salesOrderDTO.getSalesProducts().length, salesOrderDTO.getParts().length);
        //删除旧的中间表，根据订单的id
        deleteOrderProduct(salesOrderDTO.getId());
        //插入新的中间表
        OrderProduct orderProduct = new OrderProduct();
        //将salesOrder保存到数据库中，存储订单产品信息到中间表中（产品id 订单id 数量 备注 供货时间）
        try {
            for (ProductDTO productDTO : productDTOs) {
                orderProduct.setDeliveryTime(productDTO.getDeliveryTime());
                orderProduct.setQuantity(productDTO.getQuantity());
                orderProduct.setRemark(productDTO.getRemark());
                orderProduct.setUnitPrice(productDTO.getPrice());
                orderProduct.setSalesOrderId(salesOrder.getId());
                orderProduct.setProductId(productDTO.getId());
                orderProduct.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
                orderProduct.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
                //保存到订单产品中间表数据库中
                orderProductMapper.add(orderProduct);
            }
        } catch (Exception e) {
            throw new RuntimeException("新增中间表失败");
        }
    return true;
    }

    /**
     * 根据订单id删除该订单对应的中间表
     * @param id
     */
    private void deleteOrderProduct(Long id) {
        orderProductMapper.delete(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getSalesOrderId, id));
    }

    /**
     * 删除销售订单
     * @param id
     * @return
     */
    @Override
    public Boolean deleteSalesOrder(Long id) {
        return salesMapper.deleteById(id) > 0;
    }

    /**
     * get 单个销售订单
     * @param id 订单id
     * @return
     */
    @Override
    public SalesOrderVO getSalesOrder(Long id) {
        //查询销售订单表
        SalesOrder salesOrder = salesMapper.selectById(id);
        //根据订单表表的公司id 业务员id查询对应的公司和销售人员数据插入到返回对象vo中
        SalesOrderVO cas=salesMapper.findCompanyAndSalesPersonByOrder(id);
        //根据订单id查询关联的中间表数据
        LambdaQueryWrapper<OrderProduct> eq = new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getSalesOrderId, id);
        List<OrderProduct> orderProducts = orderProductMapper.selectList(eq);
        //根据中间表的数据，查询设备表，并组成返回对象vo
        List<ProductVO> productVOS =  new ArrayList<>();
        // 遍历 orderProducts，填充 productVOS
        for (OrderProduct orderProduct : orderProducts) {
            // 查询产品信息
            Product product = productMapper.selectById(orderProduct.getProductId());
            // 创建 ProductVO 并填充数据
            ProductVO productVO = new ProductVO();
            productVO.setId(product.getId());
            //productVO.setDeliveryTime(product.getDeliveryTime());
            productVO.setDescription(product.getDescription());
            productVO.setMaterial(product.getMaterial());
            productVO.setMpa(product.getMpa());
            productVO.setName(product.getName());
            productVO.setPrice(product.getPrice());
            productVO.setSpecification(product.getSpecification());
            productVO.setVersion(product.getVersion());
            productVO.setRemark(orderProduct.getRemark());
            //productVO.setQuantity(orderProduct.getQuantity());
            // 添加到 productVOS
            productVOS.add(productVO);
        }

        SalesOrderVO salesOrderVO = new SalesOrderVO(
                salesOrder.getId(),
                salesOrder.getOrderNumber(),
                cas.getCustomerCompanyName(),
                salesOrder.getTime(),
                salesOrder.getContractId(),
                productVOS,
                salesOrder.getTechnicalParameters(),
                productVOS,
                salesOrder.getSalesPersonOpinion(),
                salesOrder.getSalesPersonOpinion2(),
                salesOrder.getTechnicalPersonOpinion(),
                salesOrder.getProductionPersonOpinion(),
                salesOrder.getApprovalPersonOpinion(),
                cas.getSalesUserName(),
                cas.getTableUserName(),
                cas.getCheckUserName(),
                salesOrder.getStatus()
        );
    return salesOrderVO;
    }

    @Override
    public IPage<SalesOrderVO> selectPage(SalesOrderDTO salesOrderDTO) {
        // 1. 创建分页对象
        Page<SalesOrder> page = new Page<>(salesOrderDTO.getPageNum(), salesOrderDTO.getPageSize());

        // 2. 构建查询条件
        LambdaQueryWrapper<SalesOrder> queryWrapper = new LambdaQueryWrapper<>();

        // 按销售日期查询
        if (salesOrderDTO.getTime() != null && !salesOrderDTO.getTime().isEmpty()) {
            queryWrapper.eq(SalesOrder::getTime, salesOrderDTO.getTime());
        }

        // 按订单编号查询
        if (salesOrderDTO.getOrderNumber() != null && !salesOrderDTO.getOrderNumber().isEmpty()) {
            queryWrapper.like(SalesOrder::getOrderNumber, salesOrderDTO.getOrderNumber());
        }

        // 按客户 ID 查询
        if (salesOrderDTO.getCustomerCompanyId() != null) {
            queryWrapper.eq(SalesOrder::getCustomerCompanyId, salesOrderDTO.getCustomerCompanyId());
        }

        // 按产品或配件查询（通过关联表查询）
        if (salesOrderDTO.getSalesProducts() != null && salesOrderDTO.getSalesProducts().length > 0) {
            // 获取产品名称列表
            List<String> productNames = Arrays.stream(salesOrderDTO.getSalesProducts())
                    .map(ProductDTO::getName)
                    .collect(Collectors.toList());

            // 使用自定义 SQL 查询订单 ID
            List<Long> orderIds = salesMapper.selectOrderIdsByProductNames(productNames);
            if (!orderIds.isEmpty()) {
                queryWrapper.in(SalesOrder::getId, orderIds);
            } else {
                // 如果没有匹配的订单 ID，直接返回空结果
                return new Page<>();
            }
        }

        // 根据状态筛选
        if (salesOrderDTO.getStatus() != null && !salesOrderDTO.getStatus().isEmpty()) {
            queryWrapper.eq(SalesOrder::getStatus, salesOrderDTO.getStatus());
        }

        // 执行分页查询并转换结果
        return salesMapper.selectPage(page, queryWrapper).convert(salesOrder -> {
            SalesOrderVO vo = new SalesOrderVO();
            BeanUtils.copyProperties(salesOrder, vo);
            return vo;
        });
    }
}
